package org.hdl.anima.session;

import java.net.InetSocketAddress;
import java.util.List;

import org.hdl.anima.AppConf;
import org.hdl.anima.message.IMessage;
import org.hdl.anima.message.IPush;
import org.hdl.anima.message.IResponse;
import org.hdl.anima.message.ResponseObjWrap;
import org.hdl.anima.transport.Channel;
import org.hdl.anima.transport.ChannelHandler;
import org.hdl.anima.transport.RemoteException;

import com.google.common.base.Preconditions;

/**
 * 服务器之间通信session
 * @author qiuhd
 * @since  2014年8月13日
 */
public class LocalSession implements ISession{
	
	private final String rsid;	//远端服务器id
	private final Channel channel;//
	/**
	 * session close listener
	 */
	private SessionCloseListener listener ;
	
	public LocalSession(String rsid,Channel channel) {
		this.rsid = rsid;
		this.channel = channel;
	}

	@Override
	public String getServerId() {
		return this.rsid;
	}

	@Override
	public int getIdentity() {
		throw new UnsupportedOperationException("getIdentity");
	}
	
	public String getReconnectToken() {
		throw new UnsupportedOperationException("getReconnectToken");
	}

	@Override
	public boolean isConnected() {
		return channel.isConnected();
	}

	@Override
	public InetSocketAddress getRemoteAddress() {
		return channel.getRemoteAddress();
	}

	@Override
	public Object getAttribute(String key) {
		return channel.getAttribute(key);
	}

	@Override
	public void setAttribute(String key, Object object) {
		channel.setAttribute(key, object);
	}

	@Override
	public boolean contains(String key) {
		return channel.contains(key);
	}

	@Override
	public void removeAttribute(String key) {
		this.removeAttribute(key);
	}

	@Override
	public AppConf getConf() {
		return channel.getConf();
	}

	@Override
	public InetSocketAddress getLocalAddress() {
		return channel.getLocalAddress();
	}

	@Override
	public ChannelHandler getChannelHandler() {
		return channel.getChannelHandler();
	}
	
	public void send(int identity,Object message) throws RemoteException{
		Preconditions.checkArgument(message != null, "message is null!");
		//'Preconditions.checkArgument(identity != null, "receiver is empty or null!");
		if (message instanceof IResponse) {
			ResponseObjWrap responseWrap = new ResponseObjWrap((IMessage)message,identity);
			channel.send(responseWrap);
		}else if (message instanceof IPush){
			//TODO 处理发送推送消息
		}else {
			throw new IllegalStateException("Failed to send message,cause message clazz not match! " + message.getClass().getName()) ;
		}
	}
	
	public void send(List<Integer> receivers,IMessage message) throws RemoteException{
		
		Preconditions.checkArgument(message != null, "message is null!");
		Preconditions.checkArgument(receivers != null && receivers.size() > 0, "receiver is empty or null!");
		
		if (message instanceof IResponse) {
			ResponseObjWrap responseWrap = new ResponseObjWrap(message,receivers);
			channel.send(responseWrap);
		}else if (message instanceof IPush){
			//TODO 处理发送推送消息
		}else {
			throw new IllegalStateException("Failed to send message,cause message clazz not match! " + message.getClass().getName()) ;
		}
	}

	@Override
	public void send(Object message) throws RemoteException {
		if (message instanceof IMessage) {
			channel.send(message);
		}else {
			throw new IllegalStateException("Failed to send message ");
		}
	}

	@Override
	public void close() {
		this.channel.close();
		
		if (listener != null) {
			listener.onSessionClosed(this);
		}
	}

	@Override
	public void close(int timeout) {
		this.channel.close(timeout);
	}

	@Override
	public boolean isClosed() {
		return channel.isClosed();
	}

	@Override
	public void setlistener(SessionCloseListener listener) {
		if(this.listener != null) {
			throw new IllegalArgumentException("Failed to set up listner,cause :listener already set up");
		}
		
		this.listener = listener ;
	}
}

